﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace FranceTriple.Dal
{
    public class ForumCategoryDal
    {
        public static Int32 GetCategoryIdByTopicId(int TopicId)
        {
            Int32 categoryId;

            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    categoryId = (from c in ctx.ForumTopicSet.Include("ForumCategory")
                                  where (c.Id == TopicId)
                                  select c.ForumCategory.Id).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "GetCategoryIdByTopicId", ex.Message), ex) { EntityType = typeof(ForumCategory) };
            }
            return categoryId;
        }
        /// <summary>
        /// Remettre à zéro les compteurs : NumberOfTopic, NumberOfMessage, LastPostId et les recalculer
        /// </summary>
        public static void InitializeCategoryCounter()
        {
            List<ForumCategory> fCat;
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    fCat = (from c in ctx.ForumCategorySet.Include("ForumTopic").Include("ForumTopic.ForumPost")
                            select c).ToList();
                    foreach (var category in fCat)
                    {
                        InitializeCategoryCounter(category.Id);
                    }
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "InitializeCategoryCounter", ex.Message), ex) { EntityType = typeof(ForumCategory) };
            }
        }

        public static void InitializeCategoryCounter(Int32 CategoryId)
        {
            ForumCategory fCat;
            Int32 lastPostId;
            Int32 topicCount;
            Int32 messageCount;
            ForumPost LastPost;

            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    fCat = (from c in ctx.ForumCategorySet.Include("ForumTopic").Include("ForumTopic.ForumPost")
                            where c.Id == CategoryId
                            select c).First();

                    fCat.NumberOfTopic = 0;
                    fCat.NumberOfMessage = 0;
                    fCat.LastPostId = 0;
                    fCat.LastPostAuthor = null;
                    fCat.LastPostCreationDate = null;
                    fCat.LastPostTopicId = null;

                    topicCount = fCat.ForumTopic.Count;
                    if (topicCount > 0)
                    {
                        fCat.NumberOfTopic = topicCount;
                        foreach (var topic in fCat.ForumTopic)
                        {
                            messageCount = topic.ForumPost.Count;
                            if (messageCount > 0)
                            {
                                fCat.NumberOfMessage += messageCount;

                                lastPostId = Math.Max(fCat.LastPostId ?? 0, topic.ForumPost.Max(p1 => p1.Id));

                                if (lastPostId > 0)
                                {
                                    fCat.LastPostId = lastPostId;

                                    LastPost = ForumPostDal.GetEntity(fCat.LastPostId ?? 0);
                                    fCat.LastPostAuthor = LastPost.PostMessage.Author;
                                    fCat.LastPostCreationDate = LastPost.PostMessage.CreationDate;
                                    fCat.LastPostTopicId = ForumTopicDal.GetTopicIdByPostId(LastPost.Id);
                                }
                            }
                        }
                    }
                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "InitializeCategoryCounter", ex.Message), ex) { EntityType = typeof(ForumCategory) };
            }
        }

        public static ForumCategory GetEntity(int entityID)
        {
            ForumCategory fCat;

            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    fCat = (from c in ctx.ForumCategorySet
                            where (c.Id == entityID)
                            select c).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "ForumCategory", ex.Message), ex) { EntityType = typeof(ForumCategory) };
            }
            return fCat;
        }

        public static int CreateEntity(ForumCategory entity)
        {
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    foreach (ForumCategory c in ctx.ForumCategorySet.Include("Forum").Where(c1 =>
                        (c1.Forum.Id == entity.Forum.Id) &&
                        (c1.OrderForumCategory >= entity.OrderForumCategory)))
                    {
                        c.OrderForumCategory = c.OrderForumCategory + 10;
                    }

                    ForumCategory myCat = new ForumCategory();
                    myCat.LabelForumCategory = entity.LabelForumCategory;
                    myCat.DescriptionForumCategory = entity.DescriptionForumCategory;
                    myCat.OrderForumCategory = entity.OrderForumCategory;

                    ctx.AddToForumCategorySet(myCat);
                    myCat.Forum = (Forum)ctx.GetObjectByKey(entity.Forum.EntityKey);
                    ctx.SaveChanges();
                    return myCat.Id;
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("InsertError".ToLocalizedString(), "ForumCategory", ex.Message), ex) { EntityType = typeof(ForumCategory) };
            }
        }

        public static void UpdateEntity(ForumCategory entity, Int32 ForumId)
        {
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    var catToUpdate = ctx.ForumCategorySet.Where(c => c.Id == entity.Id).FirstOrDefault();
                    if (catToUpdate == null)
                    {
                        CreateEntity(entity);
                        return;
                    }

                    if (catToUpdate.OrderForumCategory != entity.OrderForumCategory)
                    {
                        //Utiliser la place libérée par le déplacement
                        foreach (ForumCategory f in ctx.ForumCategorySet.Where(c => c.Forum.Id == catToUpdate.Forum.Id))
                        {
                            if (f.OrderForumCategory > catToUpdate.OrderForumCategory)
                                f.OrderForumCategory = f.OrderForumCategory - 10;
                        }
                        //Décaler à partir de la nouvelle position pour créer une place
                        foreach (ForumCategory f in ctx.ForumCategorySet.Where(c => c.Forum.Id == catToUpdate.Forum.Id))
                        {

                            if (f.OrderForumCategory >= entity.OrderForumCategory)
                                f.OrderForumCategory = f.OrderForumCategory + 10;
                        }
                    }

                    catToUpdate.LabelForumCategory = entity.LabelForumCategory;
                    catToUpdate.DescriptionForumCategory = entity.DescriptionForumCategory;
                    catToUpdate.OrderForumCategory = entity.OrderForumCategory;

                    //Ne pas mettre à jour les compteurs, ici c'est une méthode sur un objet et les compteurs concernent la redondance, donc d'autres objets.
                    //catToUpdate.NumberOfMessage = entity.NumberOfMessage;
                    //catToUpdate.NumberOfTopic = entity.NumberOfTopic;
                    //catToUpdate.LastPostId = entity.LastPostId;

                    catToUpdate.Forum = (Forum)ctx.GetObjectByKey(ForumDal.GetEntity(ForumId).EntityKey);

                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("UpdateError".ToLocalizedString(), "ForumCategory", ex.Message), ex) { EntityType = typeof(ForumCategory) };
            }
        }

        public static void DeleteEntity(int entityID)
        {
            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    var catToUpdate = ctx.ForumCategorySet.Include("Forum").Where(c => c.Id == entityID).FirstOrDefault();
                    if (catToUpdate == null)
                        return;

                    foreach (ForumCategory f in ctx.ForumCategorySet.Include("Forum").Where(c => c.Forum.Id == catToUpdate.Forum.Id))
                    {
                        if (f.OrderForumCategory > catToUpdate.OrderForumCategory)
                            f.OrderForumCategory = f.OrderForumCategory - 10;
                    }

                    ctx.ForumCategorySet.DeleteObject(catToUpdate);
                    ctx.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("DeleteError".ToLocalizedString(), "ForumCategory", ex.Message), ex) { EntityType = typeof(ForumCategory) };
            }
        }

        public static ForumCategory[] GetEntities(string searchText)
        {
            ForumCategory[] res;

            try
            {
                using (FranceTriple.Dal.Model1Container ctx = new Model1Container())
                {
                    res = (from c in ctx.ForumCategorySet
                           where c.LabelForumCategory.Contains(searchText) |
                                    c.DescriptionForumCategory.Contains(searchText)
                           orderby c.OrderForumCategory, c.LabelForumCategory
                           select c).ToArray();
                }
            }
            catch (Exception ex)
            {
                LoggingManager.Logger.Log(LoggingCategory.Error, ex.Message);
                throw new DalException(String.Format("RetrieveError".ToLocalizedString(), "ForumCategory", ex.Message), ex) { EntityType = typeof(ForumCategory) };
            }
            return res;
        }
    }
}
